<script setup>
import { ref, computed, onUnmounted } from "vue";
import NoSleep from "nosleep.js";

const emit = defineEmits(["change"]);

const minute = ref(3);
const startTime = ref(0);
const endTime = ref(0);
const pauseTime = ref(0);
const state = ref(0);
const remain = ref(0);

const interval = 100;

const nosleep = new NoSleep();

function onChangeState(targetState) {
  state.value = targetState;

  switch (targetState) {
    case 1:
      onStart();
      break;
    case 2:
      onPause();
      break;
    case 3:
      onResume();
      break;
    case 4:
      onStop();
      break;

    default:
      break;
  }
}

function onShortcut(duration) {
  minute.value = duration;
  onChangeState(1);
}

function onStart() {
  if (minute.value <= 0) {
    return;
  }

  nosleep.enable();

  const now = new Date();

  startTime.value = now.getTime();
  if (minute.value >= 1) {
    now.setMinutes(now.getMinutes() + minute.value);
  } else {
    now.setSeconds(now.getSeconds() + minute.value * 60);
  }
  endTime.value = now.getTime();

  remain.value = endTime.value - startTime.value;

  emit("change", {
    percent: percent.value,
  });
}

function onPause() {
  pauseTime.value = new Date().getTime();

  nosleep.disable();
}

function onResume() {
  state.value = 1;
  const now = new Date().getTime();
  endTime.value += now - pauseTime.value;

  nosleep.enable();
}

function onStop() {
  state.value = 0;

  nosleep.disable();
}

const percent = computed(() => {
  const total = minute.value * 60;
  const val = (total - remain.value / 1000) / total;
  if (val <= 0) {
    return 0;
  }
  return val * 100;
});

const formatedRemainValue = computed(() => {
  if (remain.value <= 0) {
    return "00:00.000";
  }
  const val = remain.value / 1000;
  if (val < 60) {
    return `00:${val.toFixed(3).padStart(5, "0")}`;
  }
  const seconds = val % 60;
  const minutes = Math.floor(val / 60);
  return `${minutes.toString().padStart(2, "0")}:${seconds
    .toFixed(3)
    .padStart(5, "0")}`;
});

const timer = setInterval(() => {
  if (state.value === 2 || state.value === 0) {
    return;
  }

  const now = new Date().getTime();
  remain.value = endTime.value - now;
  if (remain.value <= 0) {
    state.value = 0;

    nosleep.disable();

    if (percent.value > 100) {
      emit("change", {
        percent: 100,
      });
    }
    return;
  }

  emit("change", {
    percent: percent.value,
  });
}, interval);

onUnmounted(() => {
  clearInterval(timer);
});

function formatTime(time) {
  if (!time) {
    return "00:00:00";
  }
  return new Date(time).toLocaleTimeString();
}

const shortcuts = [
  1, 2, 3, 4, 5, 6,
  8, 10, 12, 15, 18, 20, 25, 30,
  35, 40, 45, 50, 55, 60
]
</script>

<template>
  <div class="time-picker">
    <div class="value">
      <span>开始: {{ formatTime(startTime) }}</span>
      <span>结束: {{ formatTime(endTime) }}</span>
      <span>剩下: {{ formatedRemainValue }}</span>
    </div>
    <div class="picker">
      <span>
        <span>倒计时:</span>
        <input type="number" v-model.number="minute" />
        <span>分钟</span>
      </span>
      <span>
        <button @click="onChangeState(1)" v-show="state == 0">开始</button>
        <button @click="onChangeState(2)" v-show="state == 1">暂停</button>
        <button @click="onChangeState(3)" v-show="state == 2">继续</button>
        <button @click="onChangeState(4)" v-show="state == 1 || state === 2">停止</button>
      </span>
    </div>
    <div class="shortcuts">
      <button @click="onShortcut(1 / 6)" key="0.16666">10 秒</button>
      <button @click="onShortcut(0.5)" key="0.5">30 秒</button>
      <button @click="onShortcut(item)" v-for="item in shortcuts" :key="item">{{ item }} 分</button>
    </div>
</div>
</template>

<style scoped>
.time-picker {
  padding: 20px 5px 0 5px;
}

.value {
  display: flex;
  justify-content: space-between;
}

input {
  border: 1px solid var(--fg-color);
  border-style: none none solid none;
  width: 50px;
  /* height: 32px; */
  /* line-height: 32px; */
  padding: 2px;
  text-align: center;
  font-size: 1.2em;
}

.picker {
  display: flex;
  justify-content: space-between;
  padding: 10px 0;
}

.shortcuts {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
}

.shortcuts button {
  width: 60px;
  padding: 5px 0;
  flex-grow: 1;
}

button {
  border: 1px solid var(--bg-color);
  color: var(--bg-color);
  background-color: var(--fg-color);
  margin-left: 2px;
  padding: 5px 0;
  width: 80px;
}
</style>
